var quaC = document.getElementById('quedratic');
var quaCtx = quaC.getContext('2d');
var cubC = document.getElementById('cubic');
var cubCtx = cubC.getContext('2d');

var fixedPoint = {
    start: { x: 100, y: 150},
    end: { x: 400, y: 150}
}

/**
 * 控制点类
 */
function ControlPoint(x, y, r) {
    this.x = x || quaC.width / 2;
    this.y = y || quaC.height / 2;
    this.r = r || 5;
    this.isMousedown = false;
}
ControlPoint.ctrls = [];
ControlPoint.prototype.update = function(x, y, c) {
    // if(typeof x === 'object') {
    //     x = x.x;
    //     y = x.y;
    // }
    // this.x = x;
    // this.y = y;
    return this.HitTest(x, y, c);
}
ControlPoint.prototype.draw = function(ctx) {
    ctx.save();
    ctx.fillStyle = 'rgba(40, 40, 40, .75)';
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
    ctx.closePath();
    ctx.fill();
    ctx.restore();
}
ControlPoint.prototype.HitTest = function(x, y, c) {
    var dx = this.x - x;
    var dy = this.y - y;
    var d = Math.sqrt(dx * dx + dy * dy);
    if(d <= this.r) {
        c.style.cursor = 'all-scroll';
        return true;
    } else {
        c.style.cursor = '';
        return false;
    }
}

var ctrlPQuaC = new ControlPoint(250, 100, 5);
ControlPoint.ctrls.push(new ControlPoint(200, 100, 5));
ControlPoint.ctrls.push(new ControlPoint(300, 100, 5));

function drawFixedPoint(ctx) {
    ctx.save();
    ctx.fillStyle = 'rgba(40, 40, 40, .75)';
    ctx.beginPath();
    ctx.arc(fixedPoint.start.x, fixedPoint.start.y, 3, 0, Math.PI * 2, false);
    ctx.arc(fixedPoint.end.x, fixedPoint.end.y, 3, 0, Math.PI * 2, false);
    ctx.closePath();
    ctx.fill();
    ctx.restore();
}

function drawBackground(c, ctx) {
    ctx.clearRect(0, 0, c.width, c.height);
    ctx.fillStyle = '#ddd';
    ctx.fillRect(0, 0, c.width, c.height);
}

//绑定事件
quaC.addEventListener('mousemove', handleQuaCMousemove, false);
quaC.addEventListener('mousedown', handleQuaCMousedown, false);
quaC.addEventListener('mouseup', handleQuaCMouseup, false);
cubC.addEventListener('mousemove', handleCubCMousemove, false);
cubC.addEventListener('mousedown', handleCubCMousedown, false);
cubC.addEventListener('mouseup', handleCubCMouseup, false);
function handleQuaCMousemove(e) {
    var e = e || window.event;
    var target = e.target;
    var targetBounding = target.getBoundingClientRect();
    var mouse = {
        x: e.clientX - targetBounding.left,
        y: e.clientY - targetBounding.top
    };
    ctrlPQuaC.update(mouse.x, mouse.y, target);
    if(ctrlPQuaC.isMousedown) {
        ctrlPQuaC.x = mouse.x;
        ctrlPQuaC.y = mouse.y;
    }
}
function handleQuaCMousedown(e) {
    var e = e || window.event;
    var target = e.target;
    var targetBounding = target.getBoundingClientRect();
    var mouse = {
        x: e.clientX - targetBounding.left,
        y: e.clientY - targetBounding.top
    };
    if(ctrlPQuaC.update(mouse.x, mouse.y, target)) {
        ctrlPQuaC.isMousedown = true;
    }
}
function handleQuaCMouseup(e) {
    ctrlPQuaC.isMousedown = false;
}

function handleCubCMousemove(e) {
    var e = e || window.event;
    var target = e.target;
    var targetBounding = target.getBoundingClientRect();
    var mouse = {
        x: e.clientX - targetBounding.left,
        y: e.clientY - targetBounding.top
    };
    for(var i = 0; i < ControlPoint.ctrls.length; i += 1) {
        if(ControlPoint.ctrls[i].update(mouse.x, mouse.y, target)) {
            break;
        }
    }
    for(var i = 0; i < ControlPoint.ctrls.length; i += 1) {
        if(ControlPoint.ctrls[i].isMousedown) {
            ControlPoint.ctrls[i].x = mouse.x;
            ControlPoint.ctrls[i].y = mouse.y;
        }
    }
}
function handleCubCMousedown(e) {
    var e = e || window.event;
    var target = e.target;
    var targetBounding = target.getBoundingClientRect();
    var mouse = {
        x: e.clientX - targetBounding.left,
        y: e.clientY - targetBounding.top
    };
    for(var i = 0; i < ControlPoint.ctrls.length; i += 1) {
        if(ControlPoint.ctrls[i].update(mouse.x, mouse.y, target)) {
            ControlPoint.ctrls[i].isMousedown = true;
            break;
        }
    }
}
function handleCubCMouseup(e) {
    for(var i = 0; i < ControlPoint.ctrls.length; i += 1) {
        ControlPoint.ctrls[i].isMousedown = false;
    }
}

function drawQuaCurve(ctx) {
    ctx.save();
    ctx.strokeStyle = '#00bbff';
    ctx.beginPath();
    ctx.moveTo(fixedPoint.start.x, fixedPoint.start.y);
    ctx.quadraticCurveTo(ctrlPQuaC.x, ctrlPQuaC.y, fixedPoint.end.x, fixedPoint.end.y);
    ctx.stroke();
    ctx.restore();
}

function darwCubCurve(ctx) {
    var ctrls = ControlPoint.ctrls;
    ctx.save();
    ctx.strokeStyle = '#00bbff';
    ctx.beginPath();
    ctx.moveTo(fixedPoint.start.x, fixedPoint.start.y);
    ctx.bezierCurveTo(ctrls[0].x, ctrls[0].y, ctrls[1].x, ctrls[1].y, fixedPoint.end.x, fixedPoint.end.y);
    ctx.stroke();
    ctx.restore();
}

(function animate() {
    requestAnimationFrame(animate);
    drawBackground(quaC, quaCtx);
    drawBackground(cubC, cubCtx);

    drawFixedPoint(quaCtx);
    drawFixedPoint(cubCtx);

    ctrlPQuaC.draw(quaCtx);
    for(var i = 0; i < ControlPoint.ctrls.length; i += 1) {
        ControlPoint.ctrls[i].draw(cubCtx);
    }

    drawQuaCurve(quaCtx);
    darwCubCurve(cubCtx);

})();